//
//  ILBleUtil.h
//  IMIHome
//
//  Created by 严敏 on 2020/9/15.
//  Copyright © 2020 上海创米科技有限公司. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>
#import "ILBlePeripheral.h"

//#if defined(__has_include) && __has_include(<IMILabSDK_Base/IMISingleton.h>)
#if (IMI_LAB_SDK)
#import <IMILabKit/IMISingleton.h>
#else
#import "IMISingleton.h"
#endif

typedef void(^ILBleBlock)(void);

#define IL_BLE_API [ILBleUtil sharedInstance]

static NSString * const ILBleStateChangeNotifiName = @"ILBleStateChangeNotifiName";

NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, ILCBManagerState) {
    ILCBManagerState_Unknown = 0,//状态未知，更新迫在眉睫。
    ILCBManagerState_Resetting,//与系统服务的连接暂时丢失，即将更新。
    ILCBManagerState_Unsupported,//该平台不支持蓝牙低能耗中央/客户端角色。
    ILCBManagerState_Unauthorized,//应用程序未被授权使用蓝牙低能耗中央/客户端角色。
    ILCBManagerState_PoweredOff,//蓝牙目前处于关闭状态
    ILCBManagerState_PoweredOn,//蓝牙目前处于开机状态，可以使用。
};

typedef NS_ENUM(NSInteger, ILCBPeripheralState) {
    ILCBPeripheralState_Disconnected = 0,//设备已断开
    ILCBPeripheralState_Connecting,//设备连接中
    ILCBPeripheralState_Connected,//设备已连接
    ILCBPeripheralState_Disconnecting,//设备断开中
};

typedef void (^IL_BleStateChange_Block)(ILCBManagerState state);//设备状态改变的委托
typedef void (^IL_ScanDevices_Block)(ILBlePeripheral *peripheral, NSArray<ILBlePeripheral *> *devices, BOOL scanEnd);//找到设备的委托
typedef void (^IL_Connect_Block)(ILBlePeripheral *peripheral, NSError *error);//连接设备成功的block
typedef void (^IL_Disconnect_Block)(ILBlePeripheral *peripheral, NSError *error);//断开设备连接的bock
typedef void (^IL_ScanServices_Block)(ILBlePeripheral *peripheral, NSArray<CBService *> *services, NSError *error);//找到服务的block
typedef void (^IL_ScanCharacteristics_Block)(ILBlePeripheral *peripheral, CBService *service, NSArray<CBCharacteristic *> *characteristics, NSError *error);//发现Characteristics
typedef void (^IL_WriteValue_Block)(ILBlePeripheral *peripheral, CBCharacteristic *characteristic, NSError *error);//写Characteristic成功后的block
typedef void (^IL_NotifyStateChange_Block)(ILBlePeripheral *peripheral, CBCharacteristic *characteristic, NSError *error);//characteristic订阅状态改变的block
typedef void (^IL_UpdateValue_Block)(ILBlePeripheral *peripheral, CBCharacteristic *characteristic, NSError *error);//获取到最新Characteristics值的block

typedef void (^IL_ScanDescriptors_Block)(ILBlePeripheral *peripheral, CBCharacteristic *characteristic, NSError *error);//找Descriptor
typedef void (^IL_WriteDescriptor_Block)(ILBlePeripheral *peripheral, CBDescriptor *descriptor, NSError *error);//写Descriptor值成功后的block
typedef void (^IL_UpdateDescriptor_Block)(ILBlePeripheral *peripheral, CBDescriptor *descriptor, NSError *error);//获取到最新Descriptor值的block

typedef BOOL (^IL_ScanDevicesFilter_Block)(ILBlePeripheral *peripheral);

typedef NSString *_Nullable(^IL_GetMacAddress_Block)(ILBlePeripheral *peripheral);

@interface ILBleUtil : NSObject
IMI_SINGLETON_H

@property(nonatomic, copy) IL_BleStateChange_Block bleStateChangeBlock;//设备状态改变的委托
@property(nonatomic, copy) IL_ScanDevices_Block scanDevicesBlock;//找到设备的委托
@property(nonatomic, copy) IL_Connect_Block connectBlock;//连接设备成功callback
@property(nonatomic, copy) IL_Disconnect_Block disconnectBlock;//断开设备连接的bock
@property(nonatomic, copy) IL_ScanServices_Block scanServicesBlock;//找到服务的委托
@property(nonatomic, copy) IL_ScanCharacteristics_Block scanCharacteristicsBlock;//断开设备连接的bock
@property(nonatomic, copy) IL_WriteValue_Block writeValueBlock;//写Characteristic成功后的block
@property(nonatomic, copy) IL_NotifyStateChange_Block notifyStateChangeBlock;//characteristic订阅状态改变的block
@property(nonatomic, copy) IL_UpdateValue_Block updateValueBlock;//获取到最新Characteristics值的block


@property(nonatomic, copy) IL_ScanDescriptors_Block scanDescriptorsBlock;//找Descriptor
@property(nonatomic, copy) IL_WriteDescriptor_Block writeDescriptorBlock;//写Descriptor值成功后的block
@property(nonatomic, copy) IL_UpdateDescriptor_Block updateDescriptorBlock;//获取到最新Descriptor值的block

@property(nonatomic, copy) IL_ScanDevicesFilter_Block scanDevicesFilterBlock;//设置扫描设备过滤器
@property(nonatomic, copy) IL_GetMacAddress_Block getMacAddressBlock;//设置扫描设备过滤器

/// 已连接的外设
@property(nonatomic, strong) NSMutableArray <CBPeripheral *>*connectedPeripherals;

/**
 * 获取蓝牙状态
 * @return
 */
- (ILCBManagerState)getCBManagerState;

/**
 * 是否扫描中
 * @return
 */
- (BOOL)isScanning;

/**
 * 开启扫描
 */
- (void)startScanPeripherals:(NSInteger)timeoutInSeconds allowDuplicates:(BOOL)allowDuplicates serviceUUIDs:(NSArray<NSString *> *)serviceUUIDs;

/**
 * 停止扫描
 */
- (void)stopScanPeripherals;

/**
 * 获取扫描到的设备
 */
- (NSArray<ILBlePeripheral *> *)getDiscoverPeripherals;

/**
 * 获取扫描到的指定identifier设备
 */
- (ILBlePeripheral *)getDiscoverPeripheral:(NSString *)identifier;

/**
 * 获取指定service
 */
- (CBService *)getPeripheralService:(ILBlePeripheral *)peripheral service:(NSString *)service;

/**
 * 获取指定characteristic
 */
- (CBCharacteristic *)getPeripheralCharacteristic:(CBService *)service characteristic:(NSString *)characteristic;

/**
 * 获取指定characteristic
 */
- (CBCharacteristic *)getPeripheralCharacteristic:(ILBlePeripheral *)peripheral service:(NSString *)service characteristic:(NSString *)characteristic;


/**
 * 获取设备状态
 */
- (ILCBPeripheralState)getPeripheralState:(ILBlePeripheral *)peripheral;

/**
 * 连接设备
 */
- (void)connectPeripheral:(ILBlePeripheral *)peripheral;

/**
 * 断开设备
 */
- (void)disconnectPeripheral:(ILBlePeripheral *)peripheral;

/// 断开所有已连接设备
- (void)disconnectAllPeripheral;

/// 断开设备
/// @param peripheral <#peripheral description#>
/// @param completBlock <#completeBlock description#>
- (void)disconnectPeripheral:(ILBlePeripheral *)peripheral complet:(ILBleBlock)completBlock;

/**
 * 搜索Service
 */
- (void)discoverServices:(ILBlePeripheral *)peripheral serviceUUIDs:(NSArray<NSString *> *)serviceUUIDs;

/**
 * 搜索Characteristic
 */
- (void)discoverCharacteristics:(ILBlePeripheral *)peripheral service:(NSString *)service characteristicUUIDs:(NSArray<NSString *> *)characteristicUUIDs;

/**
 * 读取Characteristic的value
 */
- (void)read:(ILBlePeripheral *)peripheral service:(NSString *)service characteristic:(NSString *)characteristic;

/**
 * 写入Characteristic的value
 */
- (void)write:(ILBlePeripheral *)peripheral service:(NSString *)service characteristic:(NSString *)characteristic value:(NSData *)value;

/**
 * 写入加密的Characteristic的value
 */
- (void)writeEncrypt:(ILBlePeripheral *)peripheral service:(NSString *)service characteristic:(NSString *)characteristic value:(NSData *)value encryptKey:(NSData *)encryptKey;

/**
 * 写入Characteristic的value-无返回响应
 */
- (void)writeWithoutResponse:(ILBlePeripheral *)peripheral service:(NSString *)service characteristic:(NSString *)characteristic value:(NSData *)value;

/**
 * 写入加密的Characteristic的value-无返回响应
 */
- (void)writeEncryptWithoutResponse:(ILBlePeripheral *)peripheral service:(NSString *)service characteristic:(NSString *)characteristic value:(NSData *)value encryptKey:(NSData *)encryptKey;

/**
 * 写入Characteristic的value的通用方法
 */
- (void)writeImpl:(ILBlePeripheral *)peripheral service:(NSString *)service characteristic:(NSString *)characteristic value:(NSData *)value hasAck:(BOOL)hasAck encryptKey:(NSData *)encryptKey;

/**
 * 设置Characteristic是否开启Notify
 */
- (void)setNotify:(ILBlePeripheral *)peripheral service:(NSString *)service characteristic:(NSString *)characteristic flag:(BOOL)enabled;

- (void)discoverDescriptors:(ILBlePeripheral *)peripheral service:(NSString *)service characteristic:(NSString *)characteristic;

- (void)writeDescriptor:(ILBlePeripheral *)peripheral service:(NSString *)service characteristic:(NSString *)characteristic descriptor:(NSString *)descriptor value:(NSData *)value;


+ (NSString *)dataToHexString:(NSData *)data;

+ (NSData *)hexStringToData:(NSString *)str;
@end

NS_ASSUME_NONNULL_END
